using System.Collections.Generic;


using OhioState.Math;

namespace OhioState.Graphics.Proxy
{
    using Vertex = Vector3;

    public class BoxSlicer : ISliceable
    {
        private BoundingBox _box;
        public BoxSlicer(BoundingBox box)
        {
            _box = new BoundingBox(box);
            _boxVertex = new BoxVertex[8];
            for (int i = 0; i < _boxVertex.Length; i++)
            {
                _boxVertex[i] = new BoxVertex();
                _boxVertex[i]._Neighbor[0] = new Neighbor();
                _boxVertex[i]._Neighbor[1] = new Neighbor();
                _boxVertex[i]._Neighbor[2] = new Neighbor();
            }
            _activeEdgeList = new ActiveEdgeList();
            _edgeAccessFlag = new int[8, 8];
            _currentSlice = new List<Vector3>(6);
 
            // set the box topological info in ROI space
            InitBox();
        }
        private List<Vector3> _currentSlice;
        public List<Vector3> CurrentSlice
        {
            get { return _currentSlice; }
        }
        private Vector3 _point;
        public Vector3 Point
        {
            get { return _point; }
            set { _point = value; }
        }
        public void BeginSlicing(Vector3 direction)
        {

            Vector3 n = direction;
            _boxVertex[0]._Neighbor[0].Cos_theta = Vector3.dot(n, _boxVertex[0]._Neighbor[0].Edge_dir);
            _boxVertex[0]._Neighbor[1].Cos_theta = Vector3.dot(n, _boxVertex[0]._Neighbor[1].Edge_dir);
            _boxVertex[0]._Neighbor[2].Cos_theta = Vector3.dot(n, _boxVertex[0]._Neighbor[2].Edge_dir);

            _boxVertex[1]._Neighbor[0].Cos_theta = Vector3.dot(n, _boxVertex[1]._Neighbor[0].Edge_dir);
            _boxVertex[1]._Neighbor[1].Cos_theta = Vector3.dot(n, _boxVertex[1]._Neighbor[1].Edge_dir);
            _boxVertex[1]._Neighbor[2].Cos_theta = Vector3.dot(n, _boxVertex[1]._Neighbor[2].Edge_dir);

            _boxVertex[2]._Neighbor[0].Cos_theta = Vector3.dot(n, _boxVertex[2]._Neighbor[0].Edge_dir);
            _boxVertex[2]._Neighbor[1].Cos_theta = Vector3.dot(n, _boxVertex[2]._Neighbor[1].Edge_dir);
            _boxVertex[2]._Neighbor[2].Cos_theta = Vector3.dot(n, _boxVertex[2]._Neighbor[2].Edge_dir);

            _boxVertex[3]._Neighbor[0].Cos_theta = Vector3.dot(n, _boxVertex[3]._Neighbor[0].Edge_dir);
            _boxVertex[3]._Neighbor[1].Cos_theta = Vector3.dot(n, _boxVertex[3]._Neighbor[1].Edge_dir);
            _boxVertex[3]._Neighbor[2].Cos_theta = Vector3.dot(n, _boxVertex[3]._Neighbor[2].Edge_dir);

            _boxVertex[4]._Neighbor[0].Cos_theta = Vector3.dot(n, _boxVertex[4]._Neighbor[0].Edge_dir);
            _boxVertex[4]._Neighbor[1].Cos_theta = Vector3.dot(n, _boxVertex[4]._Neighbor[1].Edge_dir);
            _boxVertex[4]._Neighbor[2].Cos_theta = Vector3.dot(n, _boxVertex[4]._Neighbor[2].Edge_dir);

            _boxVertex[5]._Neighbor[0].Cos_theta = Vector3.dot(n, _boxVertex[5]._Neighbor[0].Edge_dir);
            _boxVertex[5]._Neighbor[1].Cos_theta = Vector3.dot(n, _boxVertex[5]._Neighbor[1].Edge_dir);
            _boxVertex[5]._Neighbor[2].Cos_theta = Vector3.dot(n, _boxVertex[5]._Neighbor[2].Edge_dir);

            _boxVertex[6]._Neighbor[0].Cos_theta = Vector3.dot(n, _boxVertex[6]._Neighbor[0].Edge_dir);
            _boxVertex[6]._Neighbor[1].Cos_theta = Vector3.dot(n, _boxVertex[6]._Neighbor[1].Edge_dir);
            _boxVertex[6]._Neighbor[2].Cos_theta = Vector3.dot(n, _boxVertex[6]._Neighbor[2].Edge_dir);

            _boxVertex[7]._Neighbor[0].Cos_theta = Vector3.dot(n, _boxVertex[7]._Neighbor[0].Edge_dir);
            _boxVertex[7]._Neighbor[1].Cos_theta = Vector3.dot(n, _boxVertex[7]._Neighbor[1].Edge_dir);
            _boxVertex[7]._Neighbor[2].Cos_theta = Vector3.dot(n, _boxVertex[7]._Neighbor[2].Edge_dir);

            _nearestVertexID = GetNearestVertexID(direction);
            _farthestVertexID = GetFarthestVertexID(direction);

            //Add start point and end point for slice plane (Ignore for ROI)

            _currentSlice.Add(_boxVertex[_nearestVertexID].Pos);
            _currentSlice.Add(Point);

            // initialize a first slice which is the nearest vertex (a degenerated polygon)
            InitActiveEdgeList();

            // initialize the number of slices
            _numSlices = 0;
        }
        //public Vector3 GetNearestVertex
        //{
        //    get { return _boxVertex[_nearestVertexID].Pos; }
        //}

        public bool AdvanceSlice(float step)
        {
            _currentSlice.Clear();
            int i, j;
            float t;				// used to check the correctness of the point, t should be between 0 to 1
            bool inside_flag;
            float[] delta = new float[12];		// delta component on each edge
            // initialize the advance delta for each edge
            for (i = 0; i < _activeEdgeList.NumEdges; i++)
            {
                delta[i] = step;
                _activeEdgeList.Active_edge[i].Is_computed = false;
            }
            // Compute the next slice from the current slice
            while (true)
            {
                inside_flag = true;
                for (i = 0; i < _activeEdgeList.NumEdges; i++)
                {
                    // advance edge here
                    ActiveEdge cur_edge = _activeEdgeList.Active_edge[i];
                    // if this edge has been computed, try next
                    if (cur_edge.Is_computed) continue;
                    int start_vertex = cur_edge.Vertex_id[0];
                    int end_vertex = cur_edge.Vertex_id[1];
                    float passed_delta = (cur_edge.Length - cur_edge.Sum_delta) * cur_edge.Cos_theta;
                    float edge_delta;
                    edge_delta = delta[i] / cur_edge.Cos_theta;
                    cur_edge.Sum_delta += edge_delta;
                    cur_edge.Is_computed = true;
                    t = cur_edge.Sum_delta / cur_edge.Length;
                    if (t > 1 || t < 0)
                    {
                        inside_flag = false;
                        ActiveEdge[] new_edges = new ActiveEdge[3];
                        int count = 0; // count the number of new edges;
                        for (j = 0; j < 3; j++)
                        {
                            int new_start, new_end;
                            new_start = end_vertex;
                            new_end = _boxVertex[end_vertex]._Neighbor[j].ID;
                            if (_edgeAccessFlag[new_start, new_end] == 0)
                            {
                                // set the access flag
                                _edgeAccessFlag[new_start, new_end] = 1;
                                _edgeAccessFlag[new_end, new_start] = 1;
                                // insert new edge
                                ActiveEdge e = new ActiveEdge();
                                e.Vertex_id[0] = new_start;
                                e.Vertex_id[1] = new_end;
                                e.Sum_delta = 0.0f;
                                e.Cos_theta = _boxVertex[new_start]._Neighbor[j].Cos_theta;
                                e.Length = (new Vector3(_boxVertex[new_start].Pos - _boxVertex[new_end].Pos)).Length();
                                e.Is_computed = false;
                                new_edges[count] = e;
                                count++;
                            }
                        }
                        if (count == 2)
                        { // two new edges will be inserted, current edge deleted
                            // swap the new inserted edge order such that they observe CCW
                            if (start_vertex == _boxVertex[end_vertex]._Neighbor[1].ID)
                            {
                                new_edges[2] = new_edges[0];
                                new_edges[0] = new_edges[1];
                                new_edges[1] = new_edges[2];
                            }
                            // move back the untouched edges
                            for (j = _activeEdgeList.NumEdges - 1; j >= i + 1; j--)
                            {
                                _activeEdgeList.Active_edge[j + 1] = _activeEdgeList.Active_edge[j];
                                delta[j + 1] = delta[j];
                            }
                        }
                        else if (count == 0)
                        {  // no new edge, the current edge deleted
                            // move forward the untouched edges
                            for (j = i + 1; j < _activeEdgeList.NumEdges; j++)
                            {
                                _activeEdgeList.Active_edge[j - 1] = _activeEdgeList.Active_edge[j];
                                delta[j - 1] = delta[j];
                            }
                        }
                        else
                        {   // one new edge inserted, the current edge deleted, no moving for other edges
                        }

                        // insert the new edges
                        float effective_delta = delta[i];
                        for (j = 0; j < count; j++)
                        {
                            _activeEdgeList.Active_edge[i + j] = new_edges[j];
                            delta[i + j] = effective_delta - passed_delta;
                        }
                        _activeEdgeList.NumEdges += count - 1;
                        if (!inside_flag) break;   // calculate the new correct slice
                    }
                    else
                    {
                        // add the intersection point to the slice geometry
                        Vertex a = new Vertex();
                        Vertex b = new Vertex();
                        Vertex p = new Vertex();
                        a = _boxVertex[start_vertex].Pos;
                        b = _boxVertex[end_vertex].Pos;
                        p = (1 - t) * a + t * b;
                        _currentSlice.Add(p);
                    }
                } // end for i
                if (inside_flag)
                {
                    _numSlices += (_currentSlice.Count > 0 ? 1 : 0);
                    return (_currentSlice.Count > 0);
                }
            } // end while(1)
        }
        public void EndSlicing()
        {
        }
        // The permutation of the vertex index on the box
        // the vertex order is as follows.  0123 is back face and 4567 is front face
        //
        //       Y
        //       |
        //       3------2
        //      /|     /|
        //     / |    / |
        //    7------6  |
        //    |  |   |  |
        //    |  0---|--1-->X
        //    | /    | /
        //    |/     |/
        //    4------5
        //   /
        //  Z

        //
        // the array of box vertices, the index is as above
        //
        private BoxVertex[] _boxVertex;
        private ActiveEdgeList _activeEdgeList;
        //
        // access matrix for the edges. The edges are defined by the adjacent matrix of the vertices.
        //
        private int[,] _edgeAccessFlag;
        //
        // the index of the nearest vertex where slice begins
        //
        private int _nearestVertexID;
        //
        // the index of the farthest vertex where slice ends
        //
        private int _farthestVertexID;
        private int _numSlices;

        #region private methods
        //
        // Initialize box information
        //
        private void InitBox()
        {
            Vertex v0 = new Vertex(_box.LowerLeft);
            Vertex v1 = new Vertex();
            Vertex v2 = new Vertex();
            Vertex v3 = new Vertex();
            Vertex v4 = new Vertex();
            Vertex v5 = new Vertex();
            Vertex v6 = new Vertex(_box.UpperRight);
            Vertex v7 = new Vertex();

            //
            // Set the origin and the farthest vertices in ROI space from m_BBox
            // Note BoundingBox is defined in world space, BoundingBox.LowerLeft is the origin of ROI space,
            // and BoundingBox.UpperRight is the farthest vertex on the box
            //
            //v0 = m_BBox.v0; //Vertex(0, 0, 0);
            //BoundingBox bBox = _boundingVolume as BoundingBox;
            //if (bBox != null)
            //{
            //    v0 = Vector4.homogenize(_roiBoxProxy.GetWorldToRoiMatrix() * new Vector4(bBox.LowerLeft, 1.0f));
            //    v6 = Vector4.homogenize(_roiBoxProxy.GetWorldToRoiMatrix() * new Vector4(bBox.UpperRight, 1.0f));
            //}

            //
            // Set the other 6 vertices on the box in ROI space
            //
            v1[0] = v6[0]; v1[1] = v0[1]; v1[2] = v0[2];
            v2[0] = v6[0]; v2[1] = v6[1]; v2[2] = v0[2];
            v3[0] = v0[0]; v3[1] = v6[1]; v3[2] = v0[2];
            v4[0] = v0[0]; v4[1] = v0[1]; v4[2] = v6[2];
            v5[0] = v6[0]; v5[1] = v0[1]; v5[2] = v6[2];
            v7[0] = v0[0]; v7[1] = v6[1]; v7[2] = v6[2];

            //
            // the neighbor vertices are arranged in CCW
            //
            _boxVertex[0].ID = 0;									// initialize v0 point
            _boxVertex[0].Pos = v0;
            _boxVertex[0]._Neighbor[0].ID = 1;
            _boxVertex[0]._Neighbor[0].Edge_dir[0] = 1.0f;
            _boxVertex[0]._Neighbor[0].Edge_dir[0] = 1.0f;
            _boxVertex[0]._Neighbor[0].Edge_dir[1] = 0.0f;
            _boxVertex[0]._Neighbor[0].Edge_dir[2] = 0.0f;
            _boxVertex[0]._Neighbor[1].ID = 4;
            _boxVertex[0]._Neighbor[1].Edge_dir[0] = 0.0f;
            _boxVertex[0]._Neighbor[1].Edge_dir[1] = 0.0f;
            _boxVertex[0]._Neighbor[1].Edge_dir[2] = 1.0f;
            _boxVertex[0]._Neighbor[2].ID = 3;
            _boxVertex[0]._Neighbor[2].Edge_dir[0] = 0.0f;
            _boxVertex[0]._Neighbor[2].Edge_dir[1] = 1.0f;
            _boxVertex[0]._Neighbor[2].Edge_dir[2] = 0.0f;

            _boxVertex[1].ID = 1;									// initialize v1 point
            _boxVertex[1].Pos = v1;
            _boxVertex[1]._Neighbor[0].ID = 0;
            _boxVertex[1]._Neighbor[0].Edge_dir[0] = -1.0f;
            _boxVertex[1]._Neighbor[0].Edge_dir[1] = 0.0f;
            _boxVertex[1]._Neighbor[0].Edge_dir[2] = 0.0f;
            _boxVertex[1]._Neighbor[1].ID = 2;
            _boxVertex[1]._Neighbor[1].Edge_dir[0] = 0.0f;
            _boxVertex[1]._Neighbor[1].Edge_dir[1] = 1.0f;
            _boxVertex[1]._Neighbor[1].Edge_dir[2] = 0.0f;
            _boxVertex[1]._Neighbor[2].ID = 5;
            _boxVertex[1]._Neighbor[2].Edge_dir[0] = 0.0f;
            _boxVertex[1]._Neighbor[2].Edge_dir[1] = 0.0f;
            _boxVertex[1]._Neighbor[2].Edge_dir[2] = 1.0f;

            _boxVertex[2].ID = 2;									// initialize v2 point
            _boxVertex[2].Pos = v2;
            _boxVertex[2]._Neighbor[0].ID = 1;
            _boxVertex[2]._Neighbor[0].Edge_dir[0] = 0.0f;
            _boxVertex[2]._Neighbor[0].Edge_dir[1] = -1.0f;
            _boxVertex[2]._Neighbor[0].Edge_dir[2] = 0.0f;
            _boxVertex[2]._Neighbor[1].ID = 3;
            _boxVertex[2]._Neighbor[1].Edge_dir[0] = -1.0f;
            _boxVertex[2]._Neighbor[1].Edge_dir[1] = 0.0f;
            _boxVertex[2]._Neighbor[1].Edge_dir[2] = 0.0f;
            _boxVertex[2]._Neighbor[2].ID = 6;
            _boxVertex[2]._Neighbor[2].Edge_dir[0] = 0.0f;
            _boxVertex[2]._Neighbor[2].Edge_dir[1] = 0.0f;
            _boxVertex[2]._Neighbor[2].Edge_dir[2] = 1.0f;

            _boxVertex[3].ID = 3;									// initialize v3 point
            _boxVertex[3].Pos = v3;
            _boxVertex[3]._Neighbor[0].ID = 0;
            _boxVertex[3]._Neighbor[0].Edge_dir[0] = 0.0f;
            _boxVertex[3]._Neighbor[0].Edge_dir[1] = -1.0f;
            _boxVertex[3]._Neighbor[0].Edge_dir[2] = 0.0f;
            _boxVertex[3]._Neighbor[1].ID = 7;
            _boxVertex[3]._Neighbor[1].Edge_dir[0] = 0.0f;
            _boxVertex[3]._Neighbor[1].Edge_dir[1] = 0.0f;
            _boxVertex[3]._Neighbor[1].Edge_dir[2] = 1.0f;
            _boxVertex[3]._Neighbor[2].ID = 2;
            _boxVertex[3]._Neighbor[2].Edge_dir[0] = 1.0f;
            _boxVertex[3]._Neighbor[2].Edge_dir[1] = 0.0f;
            _boxVertex[3]._Neighbor[2].Edge_dir[2] = 0.0f;

            _boxVertex[4].ID = 4;									// initialize v4 point
            _boxVertex[4].Pos = v4;
            _boxVertex[4]._Neighbor[0].ID = 0;
            _boxVertex[4]._Neighbor[0].Edge_dir[0] = 0.0f;
            _boxVertex[4]._Neighbor[0].Edge_dir[1] = 0.0f;
            _boxVertex[4]._Neighbor[0].Edge_dir[2] = -1.0f;
            _boxVertex[4]._Neighbor[1].ID = 5;
            _boxVertex[4]._Neighbor[1].Edge_dir[0] = 1.0f;
            _boxVertex[4]._Neighbor[1].Edge_dir[1] = 0.0f;
            _boxVertex[4]._Neighbor[1].Edge_dir[2] = 0.0f;
            _boxVertex[4]._Neighbor[2].ID = 7;
            _boxVertex[4]._Neighbor[2].Edge_dir[0] = 0.0f;
            _boxVertex[4]._Neighbor[2].Edge_dir[1] = 1.0f;
            _boxVertex[4]._Neighbor[2].Edge_dir[2] = 0.0f;

            _boxVertex[5].ID = 5;									// initialize v5 point
            _boxVertex[5].Pos = v5;
            _boxVertex[5]._Neighbor[0].ID = 1;
            _boxVertex[5]._Neighbor[0].Edge_dir[0] = 0.0f;
            _boxVertex[5]._Neighbor[0].Edge_dir[1] = 0.0f;
            _boxVertex[5]._Neighbor[0].Edge_dir[2] = -1.0f;
            _boxVertex[5]._Neighbor[1].ID = 6;
            _boxVertex[5]._Neighbor[1].Edge_dir[0] = 0.0f;
            _boxVertex[5]._Neighbor[1].Edge_dir[1] = 1.0f;
            _boxVertex[5]._Neighbor[1].Edge_dir[2] = 0.0f;
            _boxVertex[5]._Neighbor[2].ID = 4;
            _boxVertex[5]._Neighbor[2].Edge_dir[0] = -1.0f;
            _boxVertex[5]._Neighbor[2].Edge_dir[1] = 0.0f;
            _boxVertex[5]._Neighbor[2].Edge_dir[2] = 0.0f;

            _boxVertex[6].ID = 6;									// initialize v6 point
            _boxVertex[6].Pos = v6;
            _boxVertex[6]._Neighbor[0].ID = 2;
            _boxVertex[6]._Neighbor[0].Edge_dir[0] = 0.0f;
            _boxVertex[6]._Neighbor[0].Edge_dir[1] = 0.0f;
            _boxVertex[6]._Neighbor[0].Edge_dir[2] = -1.0f;
            _boxVertex[6]._Neighbor[1].ID = 7;
            _boxVertex[6]._Neighbor[1].Edge_dir[0] = -1.0f;
            _boxVertex[6]._Neighbor[1].Edge_dir[1] = 0.0f;
            _boxVertex[6]._Neighbor[1].Edge_dir[2] = 0.0f;
            _boxVertex[6]._Neighbor[2].ID = 5;
            _boxVertex[6]._Neighbor[2].Edge_dir[0] = 0.0f;
            _boxVertex[6]._Neighbor[2].Edge_dir[1] = -1.0f;
            _boxVertex[6]._Neighbor[2].Edge_dir[2] = 0.0f;

            _boxVertex[7].ID = 7;									// initialize v7 point
            _boxVertex[7].Pos = v7;
            _boxVertex[7]._Neighbor[0].ID = 3;
            _boxVertex[7]._Neighbor[0].Edge_dir[0] = 0.0f;
            _boxVertex[7]._Neighbor[0].Edge_dir[1] = 0.0f;
            _boxVertex[7]._Neighbor[0].Edge_dir[2] = -1.0f;
            _boxVertex[7]._Neighbor[1].ID = 4;
            _boxVertex[7]._Neighbor[1].Edge_dir[0] = 0.0f;
            _boxVertex[7]._Neighbor[1].Edge_dir[1] = -1.0f;
            _boxVertex[7]._Neighbor[1].Edge_dir[2] = 0.0f;
            _boxVertex[7]._Neighbor[2].ID = 6;
            _boxVertex[7]._Neighbor[2].Edge_dir[0] = 1.0f;
            _boxVertex[7]._Neighbor[2].Edge_dir[1] = 0.0f;
            _boxVertex[7]._Neighbor[2].Edge_dir[2] = 0.0f;
        }

        //
        // By flipping the slice direction, get the nearest vertex id
        //
        private int GetNearestVertexID(Vector3 N)
        // N is the slice advancing direction
        {
            return GetFarthestVertexID(-N);
        }

        //
        // Based on the slicing direction, get the farthest vertex id
        //
        private int GetFarthestVertexID(Vector3 N)
        // N is the slice advancing direction
        {
            int start_vertex;
            if (N[0] > 0)
            { //RIGHT
                if (N[1] > 0)
                { //RIGHT,TOP
                    if (N[2] > 0)
                        start_vertex = 6;			//RIGHT,TOP,FRONT
                    else
                        start_vertex = 2;			//RIGHT,TOP,BACK
                }
                else
                {	//RIGHT,BOTTOM
                    if (N[2] > 0)
                        start_vertex = 5;			//RIGHT,BOTTOM,FRONT
                    else
                        start_vertex = 1;			//RIGHT,BOTTOM,BACK
                }
            }
            else
            {	//LEFT
                if (N[1] > 0)
                {//LEFT,TOP
                    if (N[2] > 0)
                        start_vertex = 7;			//LEFT,TOP,FRONT
                    else
                        start_vertex = 3;			//LEFT,TOP,BACK
                }
                else
                {//LEFT,BOTTOM
                    if (N[2] > 0)
                        start_vertex = 4;			//LEFT,BOTTOM,FRONT
                    else
                        start_vertex = 0;			 //LEFT,BOTTOM,BACK
                }
            }
            return start_vertex;
        }

        //
        // Set up active edges and put them into the active edge list
        //
        private void InitActiveEdgeList()
        {
            int start_vertex_id = _nearestVertexID;
            Vector3 org = _boxVertex[start_vertex_id].Pos;
            ActiveEdge e0 = new ActiveEdge();
            ActiveEdge e1 = new ActiveEdge();
            ActiveEdge e2 = new ActiveEdge();
            Vector3 tmp = new Vector3();
            //
            // First active edge
            //
            e0.Vertex_id[0] = start_vertex_id;
            e0.Vertex_id[1] = _boxVertex[start_vertex_id]._Neighbor[0].ID;
            e0.Cos_theta = _boxVertex[start_vertex_id]._Neighbor[0].Cos_theta;
            tmp = org - _boxVertex[e0.Vertex_id[1]].Pos;
            e0.Length = tmp.Length();
            e0.Is_computed = false;
            //
            // Second active edge
            //
            e1.Vertex_id[0] = start_vertex_id;
            e1.Vertex_id[1] = _boxVertex[start_vertex_id]._Neighbor[1].ID;
            e1.Cos_theta = _boxVertex[start_vertex_id]._Neighbor[1].Cos_theta;
            tmp = org - _boxVertex[e1.Vertex_id[1]].Pos;
            e1.Length = tmp.Length();
            e1.Is_computed = false;
            //
            // Third active edge
            //
            e2.Vertex_id[0] = start_vertex_id;
            e2.Vertex_id[1] = _boxVertex[start_vertex_id]._Neighbor[2].ID;
            e2.Cos_theta = _boxVertex[start_vertex_id]._Neighbor[2].Cos_theta;
            tmp = org - _boxVertex[e2.Vertex_id[1]].Pos;
            e2.Length = tmp.Length();
            e2.Is_computed = false;
            //
            // Assign new active edges to the active edge list 
            //
            _activeEdgeList.Active_edge[0] = e0;
            _activeEdgeList.Active_edge[1] = e1;
            _activeEdgeList.Active_edge[2] = e2;
            _activeEdgeList.NumEdges = 3;
            //
            // set the access flags for the initial  active edges
            //
            for (int i = 0; i < 8; i++)
                for (int j = 0; j < 8; j++)
                    _edgeAccessFlag[i, j] = 0;

            _edgeAccessFlag[e0.Vertex_id[0], e0.Vertex_id[1]] = 1;
            _edgeAccessFlag[e0.Vertex_id[1], e0.Vertex_id[0]] = 1;
            _edgeAccessFlag[e1.Vertex_id[0], e1.Vertex_id[1]] = 1;
            _edgeAccessFlag[e1.Vertex_id[1], e1.Vertex_id[0]] = 1;
            _edgeAccessFlag[e2.Vertex_id[0], e2.Vertex_id[1]] = 1;
            _edgeAccessFlag[e2.Vertex_id[1], e2.Vertex_id[0]] = 1;
        }
        #endregion
    }
}
